package com.aiapphub.BaseCode.handler.mybatisPlus;

import com.aiapphub.BaseCode.utils.EncryptUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 加密字段类型处理器（支持 BigDecimal 类型）
 * 修改点：
 * 1. 泛型类型改为 BigDecimal
 * 2. 处理 BigDecimal 到 String 的转换逻辑
 * 3. 保留两位小数精度
 */
@Component
public class BigDecimalEncryptTypeHandler extends BaseTypeHandler<BigDecimal> { // 修改泛型类型为 BigDecimal

    private static String aesKey;
    private static String aesIv;

    @Value("${encrypt.aes.key}")
    public void setAesKey(String key) {
        aesKey = key;
    }

    @Value("${encrypt.aes.iv}")
    public void setAesIv(String iv) {
        aesIv = iv;
    }

    //---------------------- 插入数据时的加密处理 ----------------------
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
                                    BigDecimal parameter, JdbcType jdbcType) throws SQLException {
        try {
            // 关键修改：BigDecimal 转换为两位小数字符串再加密
            String plainText = parameter.setScale(2, RoundingMode.HALF_UP).toString();
            String encrypted = EncryptUtil.encrypt(plainText, aesKey, aesIv);
            ps.setString(i, encrypted);
        } catch (Exception e) {
            throw new SQLException("字段加密失败，参数位置：" + i, e);
        }
    }

    //---------------------- 查询结果时的解密处理 ----------------------
    @Override
    public BigDecimal getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String encrypted = rs.getString(columnName);
        return decryptToBigDecimal(encrypted);
    }

    @Override
    public BigDecimal getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String encrypted = rs.getString(columnIndex);
        return decryptToBigDecimal(encrypted);
    }

    @Override
    public BigDecimal getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String encrypted = cs.getString(columnIndex);
        return decryptToBigDecimal(encrypted);
    }

    //---------------------- 统一解密方法 ----------------------
    private BigDecimal decryptToBigDecimal(String encrypted) throws SQLException {
        if (encrypted == null || encrypted.trim().isEmpty()) {
            return null;
        }
        try {
            // 解密后转换为 BigDecimal 并保留两位小数
            String plainText = EncryptUtil.decrypt(encrypted, aesKey, aesIv);

            // 确保解密后的结果有效并且是一个数字
            if (plainText == null || plainText.trim().isEmpty()) {
                return null;
            }

            // 去除解密后的字符串中的非数字字符
            plainText = plainText.trim();
            if (!plainText.matches("-?\\d+(\\.\\d+)?")) {  // 正则检查是否为有效数字
                throw new SQLException("解密结果不是有效的数字格式: " + plainText);
            }

            return new BigDecimal(plainText).setScale(2, RoundingMode.HALF_UP);
        } catch (Exception e) {
            throw new SQLException("字段解密失败，加密值：" + encrypted.substring(0, Math.min(8, encrypted.length())), e);
        }
    }
}